package com.stockz.ui.swing.charting.display.indicator;

import java.awt.Graphics2D;
import java.util.List;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.stockz.core.model.Bar;
import com.stockz.core.util.ListUtil;
import com.stockz.ui.swing.charting.painter.indicator.MACDIndicatorPainter;
import com.stockz.ui.swing.charting.util.UIChartingConstant.OVERLAY;

@Component
@Scope("prototype")
public class MACD extends
		AbstractDisplayableIndicatorConfiguration {

	public static class Configuration{
		private int longSpan = 90;
		private int shortSpan = 20;
		public int getLongSpan() {
			return longSpan;
		}
		public void setLongSpan(int longSpan) {
			this.longSpan = longSpan;
		}
		public int getShortSpan() {
			return shortSpan;
		}
		public void setShortSpan(int shortSpan) {
			this.shortSpan = shortSpan;
		}
	}
	
	public static double[] values(double[] barValues, int longSpan, int shortSpan){
		if(barValues != null && shortSpan > 0 && longSpan > shortSpan && barValues.length > longSpan){
			double[] values = new double[barValues.length];
			double[] shortEmas = new double[barValues.length];
			double[] longEmas = new double[barValues.length];
			double longSum = 0;
			double longMult = (double)2/(longSpan+1);
			double shortSum = 0;
			double shortMult = (double)2/(shortSpan+1);
			for(int i = barValues.length-1; i >=0; i--){

				if(i > barValues.length - shortSpan){
					shortSum += barValues[i];
				}else if(i ==  barValues.length - shortSpan){
					shortEmas[i] = shortSum/shortSpan; 
				}else{
					shortEmas[i] = (barValues[i] - shortEmas[i+1])*shortMult + shortEmas[i+1];
				}
				
				
				if(i > barValues.length - longSpan){
					longSum += barValues[i];
				}else if(i ==  barValues.length - longSpan){
					longEmas[i] = longSum/longSpan;
				}else{
					longEmas[i] =  (barValues[i] - longEmas[i+1])*longMult + longEmas[i+1];
				}
				
				values[i] = shortEmas[i] - longEmas[i];
			
			}
			return values;
		}
		return new double[0];
	}
	
	private Configuration configuration = new Configuration();
	
	@Override
	public String getFullName() {
		return "MACD";
	}

	@Override
	public String getShortName() {
		return "MACD";
	}

	@Override
	public String getDescription() {
		return getFullName()+", "+configuration.getLongSpan()+", "+configuration.getShortSpan()+", "+getBarValueType();
	}

	@Override
	public OVERLAY getOverlay() {
		return OVERLAY.INDEPENDENT;
	}

	@Override
	public boolean isOverlappable() {
		return true;
	}

	@Override
	public void paint(Graphics2D g) {
		MACDIndicatorPainter.paint(g, this, getValues());
	}

	@Override
	public Object getConfiguration() {
		return configuration;
	}

	@Override
	public void refreshValues() {
		List<Bar> barList = getStockChartPanel().getStockChartPanelState().getBarList();
		if(barList != null && barList.size() > configuration.getLongSpan()){
			double[] barValues = ListUtil.convert(barList, getBarValueType());
			setValues(values(barValues, configuration.getLongSpan(),configuration.getShortSpan()));
		}
	}

}
